﻿<h1>Basic Control Flows</h1>

<p>
The control flow code blocks in Go are much like other popular programming languages,
but there are also many differences.
This article will show these similarities and differences.
</p>

<h3>An Introduction of Control Flows in Go</h3>

<div>
There are three kinds of basic control flow code blocks in Go:
<ul>
<li>
	<code>if-else</code> two-way conditional execution block.
</li>
<li>
	<code>for</code> loop block.
</li>
<li>
	<code>switch-case</code> multi-way conditional execution block.
</li>
</ul>

There are also some control flow code blocks which are related to some certain kinds of types in Go.
<ul>
<li>
	<code>for-range</code> loop block for
	<a href="container.html#iteration">container</a> types.
</li>
<li>
	<code>type-switch</code> multi-way conditional execution block for
	<a href="interface.html#type-switch">interface</a> types.
</li>
<li>
	<code>select-case</code> block for
	<a href="channel.html#select">channel</a> types.
</li>
</ul>

<p>
Like many other popular languages, Go also supports <code>break</code>,
<code>continue</code> and <code>goto</code> code execution jump statements.
Besides these, there is a special code jump statement in Go, <code>fallthrough</code>.
</p>

<p>
Among the six kinds of control flow blocks,
except the <code>if-else</code> control flow,
the other five are called <b>breakable control flow blocks</b>.
We can use <code>break</code> statements to make executions
jump out of breakable control flow blocks.
</p>

<p>
<code>for</code> and <code>for-range</code> loop blocks are called
<b>loop control flow blocks</b>.
We can use <code>continue</code> statements to end a loop step in advance
in a loop control flow block, i.e. continue to the next iteration of the loop.
</p>

<p>
Please note, each of the above mentioned control flow blocks is a statement,
and it may contain many other sub-statements.
</p>

<p>
Above mentioned control flow statements are all the ones in narrow sense.
The mechanisms introduced in the next article,
<a href="control-flows-more.html">goroutines, deferred function calls and
panic/recover</a>, and the concurrency synchronization techniques introduced
in the later article
<a href="concurrent-synchronization-overview.html">concurrency synchronization overview</a>
can be viewed as control flow statements in broad sense.
</p>

<p>
Only the basic control flow code blocks and code jump statements will be explained
in the current article, other ones will be explained in
many other Go 101 articles later.
</p>
</div>

<a class="anchor" id="if-else"></a>
<h3><code>if-else</code> Control Flow Blocks</h3>

<div>
The full form of a <code>if-else</code> code block is like
<pre class="line-numbers"><code class="language-go">if InitSimpleStatement; Condition {
	// do something
} else {
	// do something
}
</code></pre>

<p>
<code>if</code> and <code>else</code> are keywords.
Like many other programming languages, the <code>else</code> branch is optional.
</p>

<p>
The <code>InitSimpleStatement</code> portion is also optional.
It must be a <a href="expressions-and-statements.html#simple-statements">simple statement</a> if it is present.
If it is absent, we can view it as a blank statement (one kind of simple statements).
In practice, <code>InitSimpleStatement</code> is often
a short variable declaration or a pure assignment.
A <code>Condition</code> must be an <a href="expressions-and-statements.html#expressions">expression</a> which results to a boolean value.
The <code>Condition</code> portion can be enclosed in a pair of <code>()</code> or not,
but it can't be enclosed together with the <code>InitSimpleStatement</code> portion.
</p>

<p>
If the <code>InitSimpleStatement</code> in a <code>if-else</code> block is present,
it will be executed before executing other statements in the <code>if-else</code> block.
If the <code>InitSimpleStatement</code> is absent,
then the semicolon following it is optional.
</p>

<p>
Each <code>if-else</code> control flow forms
one implicit code block, one <code>if</code> branch explicit code block
and one optional <code>else</code> branch code block.
The two branch code blocks are both nested in the implicit code block.
Upon execution, if <code>Condition</code> expression results <code>true</code>,
then the <code>if</code> branch block will get executed, otherwise,
the <code>else</code> branch block will get executed.
</p>

Example:
<pre class="line-numbers"><code class="language-go">package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	rand.Seed(time.Now().UnixNano())

	if n := rand.Int(); n%2 == 0 {
		fmt.Println(n, "is an even number.")
	} else {
		fmt.Println(n, "is an odd number.")
	}

	n := rand.Int() % 2 // this n is not the above n.
	if n % 2 == 0 {
		fmt.Println("An even number.")
	}

	if ; n % 2 != 0 {
		fmt.Println("An odd number.")
	}
}
</code></pre>

<p>
</p>

<p>
If the <code>InitSimpleStatement</code> in a <code>if-else</code> code block is a short variable declaration,
then the declared variables will be viewed as being declared in the top nesting implicit code block of the <code>if-else</code> code block.
</p>

<p>
An <code>else</code> branch code block can be implicit if the corresponding <code>else</code>
is followed by another <code>if-else</code> code block, otherwise, it must be explicit.
</p>

Example:
<pre class="line-numbers"><code class="language-go">package main

import (
	"fmt"
	"time"
)

func main() {
	if h := time.Now().Hour(); h < 12 {
		fmt.Println("Now is AM time.")
	} else if h > 19 {
		fmt.Println("Now is evening time.")
	} else {
		fmt.Println("Now is afternoon time.")
		h := h // the right one is declared above
		// The just new declared "h" variable
		// shadows the above same-name one.
		_ = h
	}

	// h is not visible here.
}
</code></pre>

<p>
</p>

</div>

<a class="anchor" id="for"></a>
<h3><code>for</code> Loop Control Flow Blocks</h3>

<div>
The full form of a <code>for</code> loop block is:
<pre class="line-numbers"><code class="language-go">for InitSimpleStatement; Condition; PostSimpleStatement {
	// do something
}
</code></pre>

<p>
<code>for</code> is a keyword.
The <code>InitSimpleStatement</code> and <code>PostSimpleStatement</code> portions
must be both simple statements, and the <code>PostSimpleStatement</code> portion
must not be a short variable declaration.
<code>Condition</code> must be an expression which result is a boolean value.
The three portions are all optional.
</p>

<p>
Unlike many other programming languages, the just mentioned three parts following
the <code>for</code> keyword can't be enclosed in a pair of <code>()</code>.
</p>

<p>
Each <code>for</code> control flow forms at least two code blocks,
one is implicit and one is explicit.
The explicit one is nested in the implicit one.
</p>

<p>
The <code>InitSimpleStatement</code> in a <code>for</code> loop block
will be executed (only once) before executing other statements in the <code>for</code> loop block.
</p>

<p>
The <code>Condition</code> expression will be evaluated at each loop step.
If the evaluation result is <code>false</code>, then the loop will end.
Otherwise the body (a.k.a., the explicit code block) of the loop will get executed.
</p>

<p>
The <code>PostSimpleStatement</code> will be executed at the end of each loop step.
</p>


A <code>for</code> loop example. The example will print the integers from
<code>0</code> to <code>9</code>.
<pre class="line-numbers"><code class="language-go">for i := 0; i < 10; i++ {
	fmt.Println(i)
}
</code></pre>

<p>
</p>

If the <code>InitSimpleStatement</code> and <code>PostSimpleStatement</code>
portions are both absent (just view them as blank statements),
their nearby two semicolons can be omitted.
The form is called as condition-only <code>for</code> loop form.
It is the same as the <code>while</code> loop in other languages.
<pre class="line-numbers"><code class="language-go">var i = 0
for ; i < 10; {
	fmt.Println(i)
	i++
}
for i < 20 {
	fmt.Println(i)
	i++
}
</code></pre>

<p>
</p>

If the <code>Condition</code> portion is absent,
compilers will view it as <code>true</code>.
<pre class="line-numbers"><code class="language-go">for i := 0; ; i++ { // <=> for i := 0; true; i++ {
	fmt.Println(i)
	if i >= 10 {
		// "break" statement will be explained below.
		break
	}
}

// The following 4 endless loops are
// equivalent to each other.
for ; true; {
}
for true {
}
for ; ; {
}
for {
}
</code></pre>

<p>
</p>

If the <code>InitSimpleStatement</code> in a <code>for</code> block is a short variable declaration statement,
then the declared variables will be viewed as being declared in the top nesting implicit code block of the <code>for</code> block.
For example, the following code snippet prints <code>012</code> instead of <code>0</code>.

<pre class="line-numbers"><code class="language-go">for i := 0; i < 3; i++ {
	fmt.Print(i)
	// The left i is a new declared variable,
	// and the right i is the loop variable.
	i := i
	// The new declared variable is modified, but
	// the old one (the loop variable) is not yet.
	i = 10
}
</code></pre>

<p>
</p>

A <code>break</code> statement can be used to make execution jump out of the
<code>for</code> loop control flow block in advance,
if the <code>for</code> loop control flow block is the innermost breakable
control flow block containing the <code>break</code> statement.

<pre class="line-numbers"><code class="language-go">i := 0
for {
	if i >= 10 {
		break
	}
	i++
	fmt.Println(i)
}
</code></pre>

<p>
</p>


A <code>continue</code> statement can be used to end the current loop step
in advance (<code>PostSimpleStatement</code> will still get executed),
if the <code>for</code> loop control flow block is the innermost
loop control flow block containing the <code>continue</code> statement.
For example, the following code snippet will print <code>13579</code>.

<pre class="line-numbers"><code class="language-go">for i := 0; i < 10; i++ {
	if i % 2 == 0 {
		continue
	}
	fmt.Print(i)
}
</code></pre>

</div>

<a class="anchor" id="switch-case"></a>
<h3><code>switch-case</code> Control Flow Blocks</h3>

<div>

<p>
<code>switch-case</code> control flow block is
one kind of conditional execution control flow blocks.
</p>

The full form a <code>switch-case</code> block is
<pre class="line-numbers"><code class="language-go">switch InitSimpleStatement; CompareOperand0 {
case CompareOperandList1:
	// do something
case CompareOperandList2:
	// do something
...
case CompareOperandListN:
	// do something
default:
	// do something
}
</code></pre>

In the full form,
<ul>
<li>
	<code>switch</code>, <code>case</code> and <code>default</code> are three keywords.
</li>
<li>
	The <code>InitSimpleStatement</code> portion must be a simple statement.
	The <code>CompareOperand0</code> portion is an expression which is viewed as
	a typed value (if it is an untyped value,
	then it is viewed as a type value of its default type),
	hence it can't be an untyped <code>nil</code>.
	<code>CompareOperand0</code> is called as switch expression in Go specification.
</li>
<li>
	Each of the <code>CompareOperandListX</code>
	(<code>X</code> may represent from <code>1</code> to <code>N</code>)
	portions must be a comma separated expression list.
	Each of these expressions shall be comparable with <code>CompareOperand0</code>.
	Each of these expressions is called as a case expression in Go specification.
	If a case expression is an untyped value,
	then it must be implicitly convertible to the type of the switch expression
	in the same <code>switch-case</code> control flow.
	If the conversion is impossible to achieve, compilation fails.
</li>
</ul>

<p>
Each <code>case CompareOperandListX:</code> or <code>default:</code>
opens (and is followed by) an implicit code block.
The implicit code block and that <code>case CompareOperandListX:</code> or <code>default:</code> forms a branch.
Each such branch is optional to be present.
We call an implicit code block in such a branch as a branch code block later.
</p>

<p>
There can be at most one <code>default</code> branch
in a <code>switch-case</code> control flow block.
</p>

<p>
Besides the branch code blocks,
each <code>switch-case</code> control flow forms two code blocks,
one is implicit and one is explicit.
The explicit one is nested in the implicit one.
All the branch code blocks are nested in the explicit one
(and nested in the implicit one indirectly).
</p>

<p>
<code>switch-case</code> control flow blocks are breakable,
so <code>break</code> statements can also be used in any branch code block
in a <code>switch-case</code> control flow block to make execution jump out of
the <code>switch-case</code> control flow block in advance.
</p>



<p>
The <code>InitSimpleStatement</code> in a <code>for</code> loop block
will be executed (only once) before executing other statements in the <code>for</code> loop block.
</p>

<p>
The <code>InitSimpleStatement</code> will get executed firstly
when a <code>switch-case</code> control flow gets executed,
then the switch <code>CompareOperand0</code> expression will be evaluated and only evaluated once.
The evaluation result is always a typed value.
The evaluation result will be compared (by using the <code>==</code> operator)
with the evaluation result of each case expression in the
<code>CompareOperandListX</code> expression lists,
from top to down and from left to right.
If a case expression is found to be equal to <code>CompareOperand0</code>,
the comparison process stops and the corresponding branch code block
of the expression will be executed.
If none case expressions are found to be equal to <code>CompareOperand0</code>,
the default branch code block (if it is present) will get executed.
</p>

A <code>switch-case</code> control flow example:
<pre class="line-numbers"><code class="language-go">package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	rand.Seed(time.Now().UnixNano())
	switch n := rand.Intn(100); n%9 {
	case 0:
		fmt.Println(n, "is a multiple of 9.")

		// Different from many other languages,
		// in Go, the execution will automatically
		// jumps out of the switch-case block at
		// the end of each branch block.
		// No "break" statement is needed here.
	case 1, 2, 3:
		fmt.Println(n, "mod 9 is 1, 2 or 3.")
		// hHre, this "break" statement is nonsense.
		break
	case 4, 5, 6:
		fmt.Println(n, "mod 9 is 4, 5 or 6.")
	// case 6, 7, 8:
		// The above case line might fail to compile,
		// for 6 is duplicate with the 6 in the last
		// case. The behavior is compiler dependent.
	default:
		fmt.Println(n, "mod 9 is 7 or 8.")
	}
}
</code></pre>

<p>
The <code>rand.Intn</code> function returns a non-negative <code>int</code>
random value which is smaller than the specified argument.
</p>

<!--
https://github.com/golang/go/issues/28357
https://github.com/golang/go/blob/5a7cfbc0117bce314c3f079ece459173b9efc854/src/cmd/compile/internal/gc/swt.go#L637
-->
<p>
Note, if any two case expressions in a <code>switch-case</code> control flow
can be detected to be equal at compile time, then a compiler may reject the latter one.
For example, the standard Go compiler thinks the <code>case 6, 7, 8</code> line
in the above example is invalid if that line is not commented out.
But other compilers may think that line is okay.
In fact, the current standard Go compiler (version 1.13)
<a href="https://github.com/golang/go/issues/28357">allows duplicate boolean case expressions</a>,
and gccgo (v8.2) allows both duplicate boolean and string case expressions.
</p>

As the comments in the above example describes,
unlike many other languages, in Go,
at the end of each branch code block, the execution will automatically
break out of the corresponding <code>switch-case</code> control block.
Then how to let the execution slip into the next branch code block?
Go provides a <code>fallthrough</code> keyword to do this task.
For example, in the following example, every branch code block
will get executed, by their orders, from top to down.

<pre class="line-numbers"><code class="language-go">rand.Seed(time.Now().UnixNano())
switch n := rand.Intn(100) % 5; n {
case 0, 1, 2, 3, 4:
	fmt.Println("n =", n)
	// The "fallthrough" statement makes the
	// execution slip into the next branch.
	fallthrough
case 5, 6, 7, 8:
	// A new declared variable also called "n",
	// it is only visible in the currrent
	// branch code block.
	n := 99
	fmt.Println("n =", n) // 99
	fallthrough
default:
	// This "n" is the switch expression "n".
	fmt.Println("n =", n)
}
</code></pre>


<p>
</p>

Please note,
<ul>
<li>
	a <code>fallthrough</code> statement must be the final statement in a branch.
</li>
<li>
	a <code>fallthrough</code> statement can't show up
	in the final branch in a <code>switch-case</code> control flow block.
</li>
</ul>

For example, the following <code>fallthrough</code> uses are all illegal.
<pre class="line-numbers"><code class="language-go">switch n := rand.Intn(100) % 5; n {
case 0, 1, 2, 3, 4:
	fmt.Println("n =", n)
	// The if-block, not the fallthrough statement,
	// is the final statement in this branch.
	if true {
		fallthrough // error: not the final statement
	}
case 5, 6, 7, 8:
	n := 99
	fallthrough // error: not the final statement
	_ = n
default:
	fmt.Println(n)
	fallthrough // error: show up in the final branch
}
</code></pre>

<p>
</p>

<p>
The <code>InitSimpleStatement</code> and <code>CompareOperand0</code> portions
in a <code>switch-case</code> control flow are both optional.
If the <code>CompareOperand0</code> portion is absent,
it will be viewed as <code>true</code>,
a typed value of the built-in type <code>bool</code>.
If the <code>InitSimpleStatement</code> portion is absent,
the semicolon following it can be omitted.
</p>

And as above has mentioned, all branches are optional.
So the following code blocks are all legal, all of them can be viewed as no-ops.

<pre class="line-numbers"><code class="language-go">switch n := 5; n {
}

switch 5 {
}

switch _ = 5; {
}

switch {
}
</code></pre>

<p>
</p>

For the latter two <code>switch-case</code> control flow blocks in the last example,
as above has mentioned, each of the absent <code>CompareOperand0</code>
portions is viewed as a typed value <code>true</code>
of the built-in type <code>bool</code>.
So the following code snippet will print <code>hello</code>.

<pre class="line-numbers"><code class="language-go">switch {
case true: fmt.Println("hello")
default: fmt.Println("bye")
}
</code></pre>


<p>
</p>

<a class="anchor" id="default-branch-placement"></a>

Another obvious difference from many other languages is
the order of the <code>default</code> branch
in a <code>switch-case</code> control flow block can be arbitrary.
For example, the following three <code>switch-case</code> control flow blocks
are equivalent to each other.
<pre class="line-numbers"><code class="language-go">switch n := rand.Intn(3); n {
case 0: fmt.Println("n == 0")
case 1: fmt.Println("n == 1")
default: fmt.Println("n == 2")
}

switch n := rand.Intn(3); n {
default: fmt.Println("n == 2")
case 0: fmt.Println("n == 0")
case 1: fmt.Println("n == 1")
}

switch n := rand.Intn(3); n {
case 0: fmt.Println("n == 0")
default: fmt.Println("n == 2")
case 1: fmt.Println("n == 1")
}
</code></pre>

<p>
</p>

</div>

<h3><code>goto</code> Statement and Label Declaration</h3>

<div>

<p>
Like many other languages, Go also supports <code>goto</code> statement.
A <code>goto</code> keyword must be followed by a label to form a statement.
A label is declared with the form <code>LabelName:</code>,
where <code>LabelName</code> must be an identifier.
A label which name is not the blank identifier must be used at least once.
</p>

<p>
A <code>goto</code> statement will make the execution jump to the next statement
following the declaration of the label used in the <code>goto</code> statement.
So a label declaration must be followed by one statement.
</p>

<p>
A label must be declared within a function body.
A use of a label can appear before or after the declaration of the label.
But a label is not visible (and can't appear) outside
the innermost code block the label is declared in.
</p>

The following example uses a <code>goto</code> statement and a label to implement a loop control flow.

<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	i := 0

Next: // here, a label is declared.
	fmt.Println(i)
	i++
	if i < 5 {
		goto Next // execution jumps
	}
}
</code></pre>

<p>
</p>

As mentioned above, a label is not visible (and can't appear)
outside the innermost code block the label is declared in.
So the following example fails to compile.

<pre class="line-numbers"><code class="language-go">package main

func main() {
goto Label1 // error
	{
		Label1:
		goto Label2 // error
	}
	{
		Label2:
	}
}
</code></pre>

<p>
</p>

<p>
Note that, if a label is declared within the scope of a variable,
then the uses of the label can't appear before the declaration of the variable.
Identifier scopes will be explained in the article
<a href="blocks-and-scopes.html">blocks and scopes in Go</a> later.
</p>

The following example also fails to compile.
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	i := 0
Next:
	if i >= 5 {
		// error: jumps over declaration of k
		goto Exit
	}

	k := i + i
	fmt.Println(k)
	i++
	goto Next

// This label is declared in the scope of k,
// but its use is outside of the scope of k.
Exit:
}
</code></pre>

<p>
The just mentioned rule <a href="https://github.com/golang/go/issues/26058">may change later</a>.
Currently, to make the above code compile okay,
we must adjust the scope of the variable <code>k</code>.
There are two ways to fix the problem in the last example.
</p>

One way is to shrink the scope of the variable <code>k</code>.
<pre class="line-numbers"><code class="language-go">func main() {
	i := 0
Next:
	if i >= 5 {
		goto Exit
	}
	// Create an explicit code block to
	// shrink the scope of k.
	{
		k := i + i
		fmt.Println(k)
	}
	i++
	goto Next
Exit:
}
</code></pre>

The other way is to enlarge the scope of the variable <code>k</code>.
<pre class="line-numbers"><code class="language-go">func main() {
	var k int // move the declaration of k here.
	i := 0
Next:
	if i >= 5 {
		goto Exit
	}

	k = i + i
	fmt.Println(k)
	i++
	goto Next
Exit:
}
</code></pre>

<p>
</p>

</div>

<h3><code>break</code> and <code>continue</code> Statements With Labels</h3>

<p>
A <code>goto</code> statement must contain a label.
A <code>break</code> or <code>continue</code> statement can also
contain a label, but the label is optional.
Generally, <code>break</code> containing labels are used in nested breakable control flow blocks
and <code>continue</code> statements containing labels are used in nested loop control flow blocks.
</p>

<p>
If a <code>break</code> statement contains a label,
the label must be declared just before a breakable control flow block
which contains the <code>break</code> statement.
We can view the label name as the name of the breakable control flow block.
The <code>break</code> statement will make execution jump out of
the breakable control flow block, even if the breakable control flow block
is not the innermost breakable control flow block containing
<code>break</code> statement.
</p>

<p>
If a <code>continue</code> statement contains a label,
the label must be declared just before a loop control flow block
which contains the <code>continue</code> statement.
We can view the label name as the name of the loop control flow block.
The <code>continue</code> statement will end the current loop step of
the loop control flow block in advance, even if the loop control flow block
is not the innermost loop control flow block containing
the <code>continue</code> statement.
</p>

The following is an example of using <code>break</code>
and <code>continue</code> statements with labels.
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func FindSmallestPrimeLargerThan(n int) int {
Outer:
	for n++; ; n++{
		for i := 2; ; i++ {
			switch {
			case i * i > n:
				break Outer
			case n % i == 0:
				continue Outer
			}
		}
	}
	return n
}

func main() {
	for i := 90; i < 100; i++ {
		n := FindSmallestPrimeLargerThan(i)
		fmt.Print("The smallest prime number larger than ")
		fmt.Println(i, "is", n)
	}
}
</code></pre>

<p>
</p>



